using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Configuration;
using Biolink.Common.Remoting.Extensions;
using BioLink.LogBook;
using BioLink.LogBook.Contracts;
using BioLink.LogBook.Service;
using BioLink.Services;

using CIS.BioTime;
using CIS.BioTime.Gate.Interfaces;
using CIS.BioTime.Services.Activity;
using CIS.BioTime.BusinessLogic.Interfaces;
using CIS.BioTime.BusinessLogic;

namespace CIS.BioTime.Gate
{
    public class GateController
    {
        ServicePublisher _servicePublisher = new ServicePublisher();
        private LogBookHost _logBookHost = null;
        
        public void Start(string path, string configFile)
        {
            
            TrafficDefaultInfo.TurnWritingOn(
                System.IO.Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                    "BioLink Solutions\\Traffic Statistic\\"
                    + System.IO.Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location)
                    + ".txt"),
                    TimeSpan.FromSeconds(10)
                );

            GenericServicePublisher.Subscribe();
            try
            {
                XmlDocument configDoc = new XmlDocument();
                try
                {
                    configDoc.Load(path + configFile);
                }
                catch (Exception ex)
                {
                    GateEventLog.Log.WriteError("Invalid GateServer configuration file format.\r\n" + ex.Message);
                    throw;
                }

                ServicesConfiguration servicesConfiguration = null;
                GateConfiguration gateConfiguration = null;
                try
                {
                    gateConfiguration = GateConfigurationIO.Read();
                    gateConfiguration.IsValid = true;
                    gateConfiguration.ConfigFileName = GateConfigurationIO.DefaultFileName;

                    ServicesCfg.Initialize(gateConfiguration.ServicesConfiguration);
                    ServiceProvider.Initialize(gateConfiguration.ServicesConfiguration);

/*
                    servicesConfiguration = (ServicesConfiguration)System.Configuration.ConfigurationManager.GetSection("biolink.services");
                    ServicesCfg.Initialize(servicesConfiguration);
                    ServiceProvider.Initialize(servicesConfiguration);

                    gateConfiguration = (GateConfiguration)System.Configuration.ConfigurationManager.GetSection("gateConfiguration");
                    gateConfiguration.ServicesConfiguration = servicesConfiguration;
                    gateConfiguration.ConfigFileName = path + configFile;
*/
                }
                catch (Exception ex)
                {
                    GateEventLog.Log.WriteError("Error loading GateServer configuration.\r\n" + ex.Message);
                    // gateConfiguration = new GateConfiguration();
                    if (gateConfiguration != null)
                        gateConfiguration.IsValid = false;
                }

                ServiceProvider.AddLocator(new InprocessServiceLocator());

                ServiceCollection services = new ServiceCollection();
                services.Add<IEntityFactoryProviderService, EntityFactoryProviderService>(delegate { return new EntityFactoryProviderService(); });
                services.Add<IGateService, GateService>(delegate { return new GateService(gateConfiguration); });
                RegisteredServices2.Services = ServiceCollection.Add(services);
                RegisteredServices2.StartServices();


/*
                RegisteredServices rs = ServicesCfg.RegisteredServices;
                rs.RegisterService(new CIS.BioTime.BusinessLogic.EntityFactoryProviderService());
                rs.RegisterService(new GateService(gateConfiguration));
                rs.StartServices();
*/
                _logBookHost = new LogBookHost(new LogBookService());
                _logBookHost.Open();
                LogBook.CaptureTrace();

                foreach (Type contract in RegisteredServices2.Services.Contracts)
                    ServicesCfg.DirectServices[contract] = RegisteredServices2.Services[contract];

                _servicePublisher.Publish(3034);

                LogBook.WriteStatusMessage("Gate service has been started", Status.Alive);
            }
            catch(Exception ex)
            {
                Trace.WriteLine("Failed to start Gate. See Details Below" + Environment.NewLine + ex);
                throw; 
            }
        }

        public void Stop()
        {
            LogBook.WriteStatusMessage("Gate service has been stopped", Status.Dead);
            ServicesCfg.RegisteredServices.StopServices();
        }
    }
}
